<template>
  <div class="article">
    <el-card class="box-card">
      <template #header>
        <div class="clearfix">
          <span>共{{ total }}条记录</span>
          <!-- 切换推荐和最新 -->
          <div class="sorter-wrapper">
            <el-button class="sorter-btn" type="primary" v-if="!sorter" @click="sorterHandler">按推荐排序</el-button>
            <el-button class="sorter-btn" type="primary" v-else @click="sorterHandler">按最新排序</el-button>
            <el-button class="sorter-btn" type="danger" @click="shiftPreview">切换预览模式</el-button>
          </div>
          <el-button style="float: right; padding: 3px 0" type="text" @click="open('add',null)">+添加面经</el-button>
        </div>
      </template>

      <!-- 数据加载状态 -->
      <div v-if="loading" class="loading-container">
        <i class="el-icon-loading"></i>
        <span>加载中...</span>
      </div>

      <!-- 错误状态 -->
      <div v-else-if="error" class="error-container">
        <i class="el-icon-error"></i>
        <span>{{ error }}</span>
        <el-button type="text" @click="loadData">重新加载</el-button>
      </div>

      <!-- 数据表格 -->
      <el-table v-else :data="tableData" stripe style="width: 100%" empty-text="暂无数据">
        <el-table-column prop="id" label="ID" width="100" />
        <el-table-column prop="creator" label="作者" width="180" />
        <el-table-column prop="stem" label="标题" min-width="300" />
        <el-table-column prop="likeCount" label="喜欢" width="100" />
        <el-table-column prop="views" label="阅读" width="100" />
        <el-table-column prop="createdAt" label="日期" width="100" />
        <el-table-column label="操作" width="180">
          <!-- 这里我们想将obj数据拿过来看看的时候 不能使用{{obj}} 因为obj是一个对象 不能直接用{{}}化成String来展示 我们可以传到del里面点击触发 log看看  -->
          <template #default="obj">
            <div class="icon-group">
              <el-tooltip class="item" effect="light" content="预览" placement="top">
                <i class="el-icon-view" @click="open('preview', obj.row.id)"></i>
              </el-tooltip>

              <el-tooltip class="item" effect="light" content="编辑" placement="top">
                <i class="el-icon-edit-outline " @click="open('edit', obj.row.id)"></i>
              </el-tooltip>

              <el-tooltip class="item" effect="light" content="删除" placement="top">
                <i class="el-icon-delete-solid " @click="del(obj.row.id)"></i>
                </el-tooltip>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <!--
current-change :当前页改变时触发
size-change :每页条数改变时触发  (不需要)
current-page :当前页
:page-sizes :每页条数
:page-size :当前页条数
layout :布局
-->
      <el-pagination background @current-change="handleCurrentChange" :current-page="current" :page-size="pageSize"
        layout="total, prev, pager, next, jumper" :total="total">
      </el-pagination>
    </el-card>
    <!--
:visible.sync 抽屉组件显示隐藏的变量
:direction 抽屉组件方向
:before-close 抽屉组件关闭前触发  一旦设置之后 抽屉就不会直接关闭了 而是会先执行这个函数 在函数内手动关闭
-->
    <el-drawer :title="drawerTitle" :visible.sync="drawerVisible" direction="ltr" :before-close="handleClose"
      size="60%">
      <!--
总结:
绑定
:model 收集的表单数据
:rules 表单校验规则
prop : rules中校验的数据的变量名
-->
      <el-form v-if="drawType !=='preview'||(drawType==='preview'&&previewModel==='old')" ref="form" :model="form"
        label-width="80px" :rules="rules">
        <el-form-item label="面经标题" prop="stem">
          <el-input v-model="form.stem" placeholder="请输入文章的标题"></el-input>
        </el-form-item>

        <el-form-item label="面经内容" prop="content">
          <!-- 富文本编辑器 -->
          <!-- 失去焦点时候 手动提示  因为quillEditor 是一个第三方组件 不属于ELement  validateField 接收一个参数 校验的字段名 prop -->
          <quillEditor v-model="form.content" @blur="$refs.form.validateField('content')"></quillEditor>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">确认</el-button>
          <el-button @click="cancelSubmit">取消</el-button>
        </el-form-item>
      </el-form>
      <!-- 下面是面经的详情页  -->
      <div class="articleDetailsPage" v-if="previewModel === 'new' && this.drawType==='preview'">
        <h5>{{form.stem}}</h5>
        <div v-html="form.content"></div>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { addArticle, delArticle, getArticleList, getArticleData, updateArticle } from '@/api/article'
import { quillEditor } from 'vue-quill-editor'

export default {
  name: 'MyArticle',
  components: {
    quillEditor
  },
  data () {
    return {
      previewModel: 'new',
      edit: null,
      current: 1,
      pageSize: 10,
      sorter: 'weight_desc',
      tableData: [],
      total: 0,
      loading: false,
      error: null,
      // 抽屉组件显示隐藏的变量
      drawerVisible: false,
      drawType: '',
      form: {
        stem: '',
        content: ''
      },
      rules: {
        stem: [
          { required: true, message: '请输入文章的标题', trigger: ['blur'] }
        ],
        content: [
          { required: true, message: '请输入文章的内容', trigger: ['blur'] }
        ]
      }
    }
  },
  methods: {
    async loadData () {
      this.loading = true
      this.error = null

      try {
        const res = await getArticleList({
          current: this.current,
          pageSize: this.pageSize,
          sorter: this.sorter
        })

        this.tableData = res.data.rows
        this.total = res.data.total
      } catch (err) {
        console.error('加载数据失败:', err)
        this.error = err.message || '加载数据失败，请稍后重试'
        this.tableData = []
        this.total = 0
      } finally {
        this.loading = false
      }
    },
    // handleCurrentChange 分页改变时触发  此事件处理函数 有一个默认的参数 value :页号
    handleCurrentChange (value) {
      this.current = value
      this.loadData()
    },
    async del (id) {
      // console.log(obj)
      // 可看出 obj是具名插槽返回的一个数据 我们可以通过obj.row 来获取到当前行的数据 还有 $index是行号
      // console.log(obj.row.id)
      // console.log(obj.$index)
      // 我们拿取id  进行删除操作即可 (不传row 直接传row.id)
      // console.log(id)

      try {
        await delArticle(id)
        this.$message.success('删除成功')
        if (this.current > 1 && this.tableData.length === 1) {
          this.current--
        }
        this.loadData()
      } catch {
        this.$message.error('删除失败')
      }
      // 我们会发现 当我们删除了最后一页的最后一条数据的时候 页面会显示暂无数据 我们需要判断一下 如果删除的是最后一页的最后一条数据 我们需要将当前页减一
    },
    sorterHandler () {
      this.sorter = this.sorter === 'weight_desc' ? null : 'weight_desc'
      this.loadData()
    },
    async open (type, id) {
      // preview  add  edit
      // console.log(type, id)
      // type 是功能
      this.edit = id
      this.drawerVisible = true
      this.drawType = type
      if (type !== 'add') {
        try {
          const res = await getArticleData(id)
          console.log(res)
          this.form.stem = res.data.stem
          this.form.content = res.data.content
        } catch {
          this.$message.error('获取数据失败')
        }
      } else {
        // 新增时重置表单
        this.form = {
          stem: '',
          content: ''
        }
      }
    },
    // 关闭抽屉组件
    handleClose (done) {
      // done是一个函数 调用了done 抽屉会关闭  也可以使用drawerVisible
      this.$confirm('确认关闭？')
        .then(() => {
          // 浏览器的对话框 alert confirm prompt 都是同步执行的 弹出会等待用户响应结果 再继续执行 同步执行会阻止页面加载渲染 ELement 提供的对话框 都是异步执行的
          done()
          // 重置表单
          this.form = {
            stem: '',
            content: ''
          }
        })
        .catch(() => {

        })
    },
    // 提交数据
    onSubmit () {
      this.$refs.form.validate(async (valid) => {
        if (!valid) {
          return
        }

        // 当用户点击确定提交的时候 需要判断是新增还是编辑 还是预览 (禁止修改)
        if (this.drawType === 'preview') {
          this.$message.error('预览模式下不能修改')
        } else if (this.drawType === 'add') {
          // 新增
          try {
            await addArticle(
              { ...this.form }
            )
            this.$message.success('添加成功')
            // 重置表单
            this.$refs.form.resetFields()
            // 刷新数据
            this.current = 1
            this.loadData()
            // 关闭抽屉
            this.drawerVisible = false
          } catch {
            this.$message.error('添加失败')
            // 重置表单
            this.$refs.form.resetFields()
          }
        } else {
          // 编辑
          try {
            await updateArticle({
              id: this.edit,
              stem: this.form.stem,
              content: this.form.content
            })
            this.$message.success('编辑成功')
            // 刷新数据
            this.loadData()
            // 关闭抽屉
            this.drawerVisible = false
          } catch {
            this.$message.error('编辑失败')
          }
        }
      })
    },
    cancelSubmit () {
      // 重置表单
      this.$refs.form.resetFields()
      // 关闭抽屉
      this.drawerVisible = false
    },
    // old版本 是复用之前的表单 新版本是使用v-html渲染出来的 点击按钮即可切换
    shiftPreview () {
      this.previewModel = this.previewModel === 'old' ? 'new' : 'old'
      if (this.previewModel === 'old') {
        this.$message.success('成功切换至旧版')
      } else {
        this.$message.success('成功切换至新版')
      }
    }
  },
  computed: {
    // 基于data中的点击传入的type 动态生成一个抽屉的标题
    drawerTitle () {
      const title = {
        preview: '预览界面',
        edit: '编辑界面',
        add: '添加面经'
      }
      return title[this.drawType] || '抽屉'
    }
  },
  created () {
    this.loadData()
  }

}
</script>

<style scoped lang="scss">
/* 深度选择器把样式打到 el-drawer 内部 */
::v-deep .el-drawer__header {
  text-align: center;
}
.article {
  padding: 20px;
}

.loading-container,
.error-container {
  text-align: center;
  padding: 40px;
  color: #909399;
}

.error-container {
  color: #f56c6c;
}

.error-container .el-button {
  margin-left: 10px;
}
.icon-group{
display: flex;
justify-content: space-around;
font-size: 28px;
 > i:hover{
cursor: pointer;
color: #0c78c0;
}
}
.sorter-wrapper {
  float: right;
  margin-left: 16px;
  .sorter-btn{
    padding: 3px 0;
    font-size: 14px;
  }
}
/* ===== 新版预览页（articleDetailsPage） ===== */
.articleDetailsPage {
  max-width: 680px;           // 内容宽度
  margin: 0 auto;             // 水平居中
  padding: 32px 24px;         // 内边距
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  line-height: 1.8;
  color: #2c3e50;

  h5 {
    font-size: 28px;
    font-weight: 600;
    text-align: center;
    margin: 0 0 24px;
    color: #1a1a1a;
  }

  /* 富文本内容区 */
  > div {
    font-size: 16px;
    color: #444;
    word-break: break-word;

    /* 常见富文本标签统一美化 */
    p { margin: 0 0 16px; }
    img { max-width: 100%; height: auto; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,.08); }
    blockquote {
      margin: 16px 0;
      padding-left: 16px;
      border-left: 4px solid #409eff;
      color: #606266;
      background: #f7f9fc;
    }
    pre {
      background: #f6f8fa;
      padding: 16px;
      border-radius: 6px;
      overflow-x: auto;
      font-size: 14px;
    }
    code {
      background: #f3f4f6;
      padding: 2px 6px;
      border-radius: 4px;
      font-size: 14px;
    }
  }

  /* 移动端适配 */
  @media (max-width: 768px) {
    padding: 24px 16px;
    h5 { font-size: 24px; }
  }
}
</style>
